home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xoct / xmoct.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  19KB  |  666 lines

  1. /*
  2. # MOTIF-BASED OCTAHEDRON
  3. #
  4. #  xmoct.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1993 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "useful",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 5: 95/10/04 Xt/Motif
  28.   Version 4: 94/05/31 Xt
  29.   Version 3: 93/04/01 Motif
  30.   Version 2: 92/02/01 XView
  31.   Version 1: 91/06/10 SunView
  32. */
  33.  
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #ifdef VMS
  37. #include <unixlib.h>
  38. #define getlogin cuserid
  39. #else
  40. #ifndef apollo
  41. #include <unistd.h>
  42. #endif
  43. #endif
  44. #include <X11/Intrinsic.h>
  45. #include <X11/StringDefs.h>
  46. #include <X11/Shell.h>
  47. #include <X11/cursorfont.h>
  48. #include <Xm/PanedW.h>
  49. #include <Xm/RowColumn.h>
  50. #include <Xm/Label.h>
  51. #include <Xm/LabelG.h>
  52. #include <Xm/Scale.h>
  53. #include <Xm/ToggleB.h>
  54. #include <Xm/ToggleBG.h>
  55. #include "Oct.h"
  56. #include "oct.xbm"
  57. #include "mouse-l.xbm"
  58. #include "mouse-r.xbm"
  59.  
  60. #ifndef SCOREFILE
  61. #define SCOREFILE "/usr/games/lib/oct.scores"
  62. #endif
  63.  
  64. /* The following are in OctP.h also */
  65. #define MINOCTAS 1
  66. #define PERIOD3 3
  67. #define PERIOD4 4
  68. #define BOTH 5
  69. #define MAXMODES 3
  70.  
  71. #define MAXOCTAS 6
  72. #define MAXRECORD 32767
  73.  
  74. static void Initialize();
  75. static void CallbackOct();
  76.  
  77. static void PrintRecord();
  78. static int HandleSolved();
  79. static void ReadRecords();
  80. static void WriteRecords();
  81.  
  82. static void OctaSlider();
  83. static void ModeToggle();
  84. static void OrientToggle();
  85. static void StickyToggle();
  86. static void PracticeToggle();
  87. static void motif_printf();
  88.  
  89. static Arg arg[5];
  90. static Widget moves, record, message, oct, modes[MAXMODES],
  91.   orientSwitch, stickySwitch, practiceSwitch, octas;
  92. static int octRecord[MAXMODES][2][MAXOCTAS - MINOCTAS + 2], movesDsp = 0;
  93. static int oldSize;
  94. static char messageDsp[128] = "Welcome";
  95.  
  96. static char *modeString[] = {
  97.   "Period 3", "Period 4", "Both"
  98. };
  99.  
  100. static void Usage()
  101. {
  102.   (void) fprintf(stderr, "usage: xmoct\n");
  103.   (void) fprintf(stderr,
  104.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  105.   (void) fprintf(stderr,
  106.     "\t[-display [{host}]:[{vs}]] [-fg {color}] [-bg {color}]\n");
  107.   (void) fprintf(stderr,
  108.     "\t[-{border|bd} {color}] [-mono] [-{size {int} | sticky}]\n");
  109.   (void) fprintf(stderr,
  110.     "\t[[-{mode {int} | both}] [-[no]orient] [-[no]practice]\n");
  111.   (void) fprintf(stderr,
  112.     "\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
  113.   exit(1);
  114. }
  115.  
  116. static XrmOptionDescRec options[] = {
  117.   {"-fg",        "*oct.Foreground",    XrmoptionSepArg,    NULL},
  118.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  119.   {"-foreground",    "*oct.Foreground",    XrmoptionSepArg,    NULL},
  120.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  121.   {"-border",        "*oct.pieceBorder",    XrmoptionSepArg,    NULL},
  122.   {"-bd",        "*oct.pieceBorder",    XrmoptionSepArg,    NULL},
  123.   {"-mono",        "*oct.mono",        XrmoptionNoArg,        "TRUE"},
  124.   {"-size",        "*oct.size",        XrmoptionSepArg,    NULL},
  125.   {"-sticky",        "*oct.sticky",        XrmoptionNoArg,        "FALSE"},
  126.   {"-mode",        "*oct.mode",        XrmoptionSepArg,    NULL},
  127.   {"-both",        "*oct.mode",        XrmoptionNoArg,        "4"},
  128.   {"-orient",        "*oct.orient",        XrmoptionNoArg,        "TRUE"},
  129.   {"-noorient",        "*oct.orient",        XrmoptionNoArg,        "FALSE"},
  130.   {"-practice",        "*oct.practice",    XrmoptionNoArg,        "TRUE"},
  131.   {"-nopractice",    "*oct.practice",    XrmoptionNoArg,        "FALSE"},
  132.   {"-face0",        "*oct.faceColor0",    XrmoptionSepArg,    NULL},
  133.   {"-face1",        "*oct.faceColor1",    XrmoptionSepArg,    NULL},
  134.   {"-face2",        "*oct.faceColor2",    XrmoptionSepArg,    NULL},
  135.   {"-face3",        "*oct.faceColor3",    XrmoptionSepArg,    NULL},
  136.   {"-face4",        "*oct.faceColor4",    XrmoptionSepArg,    NULL},
  137.   {"-face5",        "*oct.faceColor5",    XrmoptionSepArg,    NULL},
  138.   {"-face6",        "*oct.faceColor6",    XrmoptionSepArg,    NULL},
  139.   {"-face7",        "*oct.faceColor7",    XrmoptionSepArg,    NULL}
  140. };
  141.  
  142. int main(argc, argv)
  143.   int argc;
  144.   char *argv[];
  145. {
  146.   Widget toplevel; 
  147.   Widget panel, panel2, rowcol, rowcol2, rowcol3, rowcol4;
  148.   Pixmap mouseLeftCursor, mouseRightCursor;
  149.   Pixel fg, bg;
  150.   int i;
  151.  
  152.   toplevel = XtInitialize(argv[0], "Oct",
  153.     options, XtNumber(options), &argc, argv);
  154.   if (argc != 1)
  155.     Usage();
  156.  
  157.   XtSetArg(arg[0], XtNiconPixmap,
  158.     XCreateBitmapFromData(XtDisplay(toplevel),
  159.       RootWindowOfScreen(XtScreen(toplevel)),
  160.       (char *) oct_bits, oct_width, oct_height));
  161.   XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
  162.   XtSetValues(toplevel, arg, 2);
  163.   panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
  164.     NULL, 0);
  165.   panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
  166.     XmNseparatorOn, False,
  167.     XmNsashWidth, 1,
  168.     XmNsashHeight, 1,
  169.     NULL);
  170.  
  171.   rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
  172.     XmNnumColumns, 2,
  173.     XmNorientation, XmHORIZONTAL,
  174.     XmNpacking, XmPACK_COLUMN,
  175.     NULL);
  176.   XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
  177.   mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  178.     RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
  179.     mouse_left_width, mouse_left_height, fg, bg,
  180.     DefaultDepthOfScreen(XtScreen(rowcol)));
  181.   mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  182.     RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
  183.     mouse_right_width, mouse_right_height, fg, bg,
  184.     DefaultDepthOfScreen(XtScreen(rowcol)));
  185.   XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
  186.     XtVaTypedArg, XmNlabelString, XmRString, "Move", 5, NULL);
  187.   XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
  188.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
  189.   XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
  190.     XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
  191.   XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
  192.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
  193.   XtVaCreateManagedWidget("CallbackOct", xmLabelGadgetClass, rowcol,
  194.     XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
  195.   moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  196.   XtVaCreateManagedWidget("record_text", xmLabelGadgetClass, rowcol,
  197.     XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
  198.   record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  199.  
  200.   rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
  201.     NULL);
  202.   XtVaGetValues(rowcol2, XmNforeground, &fg, XmNbackground, &bg, NULL);
  203.   octas = XtVaCreateManagedWidget("octas", xmScaleWidgetClass, rowcol2,
  204.     XtVaTypedArg, XmNtitleString, XmRString, "Octas", 6,
  205.     XmNminimum, MINOCTAS,
  206.     XmNmaximum, MAXOCTAS,
  207.     XmNvalue, MINOCTAS,
  208.     XmNshowValue, True,
  209.     XmNorientation, XmHORIZONTAL,
  210.     NULL);
  211.   XtAddCallback(octas, XmNvalueChangedCallback, OctaSlider, NULL);
  212.   rowcol3 = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, rowcol2,
  213.     XmNnumColumns, 1,
  214.     XmNorientation, XmHORIZONTAL,
  215.     XmNpacking, XmPACK_COLUMN,
  216.     XmNradioBehavior, True,
  217.     NULL);
  218.   for (i = 0; i < XtNumber(modeString); i++) {
  219.     modes[i] = XtVaCreateManagedWidget(modeString[i],
  220.       xmToggleButtonGadgetClass, rowcol3,
  221.       XmNradioBehavior, True,
  222.       NULL);
  223.     XtAddCallback(modes[i], XmNvalueChangedCallback, ModeToggle,
  224.       (XtPointer) i);
  225.   }
  226.   rowcol4 = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, rowcol2,
  227.     XmNnumColumns, 1,
  228.     XmNorientation, XmHORIZONTAL,
  229.     XmNpacking, XmPACK_COLUMN,
  230.     NULL);
  231.   orientSwitch = XtVaCreateManagedWidget ("Orient",
  232.     xmToggleButtonWidgetClass, rowcol4,
  233.     NULL);
  234.   XtAddCallback(orientSwitch, XmNvalueChangedCallback, OrientToggle, NULL);
  235.   stickySwitch = XtVaCreateManagedWidget ("Sticky",
  236.     xmToggleButtonWidgetClass, rowcol4,
  237.     NULL);
  238.   XtAddCallback(stickySwitch, XmNvalueChangedCallback, StickyToggle, NULL);
  239.   practiceSwitch = XtVaCreateManagedWidget ("Practice",
  240.     xmToggleButtonWidgetClass, rowcol4,
  241.     NULL);
  242.   XtAddCallback(practiceSwitch, XmNvalueChangedCallback, PracticeToggle, NULL);
  243.   message = XtVaCreateManagedWidget("Play Oct! (use mouse and keypad)",
  244.     xmLabelWidgetClass, rowcol2,
  245.     NULL);
  246.  
  247.   oct = XtCreateManagedWidget("oct", octWidgetClass, panel,
  248.     NULL, 0);
  249.   XtAddCallback(oct, XtNselectCallback, CallbackOct, NULL);
  250.   Initialize(oct);
  251.   XtRealizeWidget(toplevel);
  252.   XGrabButton(XtDisplay(oct), AnyButton, AnyModifier, XtWindow(oct),
  253.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  254.     GrabModeAsync, GrabModeAsync, XtWindow(oct),
  255.     XCreateFontCursor(XtDisplay(oct), XC_crosshair));
  256.   XtMainLoop();
  257.  
  258. #ifdef VMS
  259.   return 1;
  260. #else
  261.   return 0;
  262. #endif
  263. }
  264.  
  265. static void Initialize(w)
  266.   Widget w;
  267. {
  268.   int size, mode;
  269.   Boolean orient, sticky, practice;
  270.  
  271.   XtVaSetValues(w,
  272.     XtNstart, FALSE,
  273.     NULL);
  274.   XtVaGetValues(w,
  275.     XtNsize, &size,
  276.     XtNmode, &mode,
  277.     XtNorient, &orient,
  278.     XtNsticky, &sticky,
  279.     XtNpractice, &practice,
  280.     NULL);
  281.   if (size <= MAXOCTAS)
  282.     XmScaleSetValue(octas, size);
  283.   XmToggleButtonSetState(modes[mode - PERIOD3], True, False);
  284.   XmToggleButtonSetState(orientSwitch, orient, True);
  285.   XmToggleButtonSetState(stickySwitch, sticky, True);
  286.   XmToggleButtonSetState(practiceSwitch, practice, True);
  287.   ReadRecords();
  288.   PrintRecord(size, mode, orient, sticky, practice);
  289.   oldSize = size;
  290. }
  291.  
  292. static void CallbackOct(w, clientData, callData)
  293.   Widget w;
  294.   caddr_t clientData;
  295.   octCallbackStruct *callData;
  296. {
  297.   int size, mode;
  298.   Boolean orient, sticky, practice, start;
  299.  
  300.   XtVaGetValues(w,
  301.     XtNsize, &size,
  302.     XtNmode, &mode,
  303.     XtNorient, &orient,
  304.     XtNsticky, &sticky,
  305.     XtNpractice, &practice,
  306.     XtNstart, &start,
  307.     NULL);
  308.   (void) strcpy(messageDsp, "");
  309.   switch (callData->reason) {
  310.     case OCT_RESTORE:
  311.       if (practice)
  312.         motif_printf(record, "practice");
  313.       movesDsp = 0;
  314.       break;
  315.     case OCT_RESET:
  316.       movesDsp = 0;
  317.       break;
  318.     case OCT_AMBIGUOUS:
  319.       (void) strcpy(messageDsp, "Ambiguous move");
  320.       break;
  321.     case OCT_ILLEGAL:
  322.       if (practice || start)
  323.         (void) strcpy(messageDsp, "Illegal move");
  324.       else
  325.         (void) strcpy(messageDsp, "Randomize to start");
  326.       break;
  327.     case OCT_MOVED:
  328.       movesDsp++;
  329.       XtSetArg(arg[0], XtNstart, TRUE);
  330.       XtSetValues(w, arg, 1);
  331.       break;
  332.     case OCT_CONTROL:
  333.       return;
  334.     case OCT_SOLVED:
  335.       if (practice)
  336.         movesDsp = 0;
  337.       else {
  338.         if (HandleSolved(movesDsp, size, mode, orient, sticky))
  339.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  340.         else
  341.           (void) strcpy(messageDsp, "Solved!");
  342.       }
  343.       XtSetArg(arg[0], XtNstart, FALSE);
  344.       XtSetValues(w, arg, 1);
  345.       break;
  346.     case OCT_PRACTICE:
  347.       movesDsp = 0;
  348.       practice = !practice;
  349.       if (!practice)
  350.         (void) strcpy(messageDsp, "Randomize to start");
  351.       PrintRecord(size, mode, orient, sticky, practice);
  352.       XtSetArg(arg[0], XtNpractice, practice);
  353.       XtSetArg(arg[1], XtNstart, FALSE);
  354.       XtSetValues(w, arg, 2);
  355.       XmToggleButtonSetState(practiceSwitch, practice, True);
  356.       break;
  357.     case OCT_RANDOMIZE:
  358.       movesDsp = 0;
  359.       XtSetArg(arg[0], XtNpractice, FALSE);
  360.       XtSetArg(arg[1], XtNstart, FALSE);
  361.       XtSetValues(w, arg, 2);
  362.       break; 
  363.     case OCT_DEC:
  364.       if (!sticky) {
  365.         movesDsp = 0;
  366.         size--;
  367.         oldSize = size;
  368.         PrintRecord(size, mode, orient, sticky, practice);
  369.         XtSetArg(arg[0], XtNsize, size);
  370.         XtSetValues(w, arg, 1);
  371.         if (size <= MAXOCTAS)
  372.           XmScaleSetValue(octas, size);
  373.       }
  374.       break;
  375.     case OCT_ORIENT:
  376.       movesDsp = 0;
  377.       orient = !orient;
  378.       PrintRecord(size, mode, orient, sticky, practice);
  379.       XtSetArg(arg[0], XtNorient, orient);
  380.       XtSetValues(w, arg, 1);
  381.       XmToggleButtonSetState(orientSwitch, orient, True);
  382.       break;
  383.     case OCT_INC:
  384.       if (!sticky) {
  385.         movesDsp = 0;
  386.         size++;
  387.         oldSize = size;
  388.         PrintRecord(size, mode, orient, sticky, practice);
  389.         XtSetArg(arg[0], XtNsize, size);
  390.         XtSetValues(w, arg, 1);
  391.         if (size <= MAXOCTAS)
  392.           XmScaleSetValue(octas, size);
  393.       }
  394.       break;
  395.     case OCT_PERIOD3:
  396.     case OCT_PERIOD4:
  397.     case OCT_BOTH:
  398.       movesDsp = 0;
  399.       mode = callData->reason - OCT_PERIOD3 + PERIOD3;
  400.       PrintRecord(size, mode, orient, sticky, practice);
  401.       XtSetArg(arg[0], XtNmode, mode);
  402.       XtSetValues(w, arg, 1);
  403.       XmToggleButtonSetState(modes[mode - PERIOD3], True, True);
  404.       break;
  405.     case OCT_STICKY:
  406.       movesDsp = 0;
  407.       sticky = !sticky;
  408.       if (sticky)
  409.         size = 4;
  410.       else
  411.         size = oldSize;
  412.       PrintRecord(size, mode, orient, sticky, practice);
  413.       XtSetArg(arg[0], XtNsticky, sticky);
  414.       XtSetArg(arg[1], XtNsize, size);
  415.       XtSetValues(w, arg, 2);
  416.       XmToggleButtonSetState(stickySwitch, sticky, True);
  417.       break;
  418.     case OCT_COMPUTED:
  419.       XtSetArg(arg[0], XtNstart, FALSE);
  420.       XtSetValues(w, arg, 1);
  421.       break;
  422.     case OCT_UNDO:
  423.       movesDsp--;
  424.       XtSetArg(arg[0], XtNstart, TRUE);
  425.       XtSetValues(w, arg, 1);
  426.       break;
  427.   }
  428.   motif_printf(message, "%s", messageDsp);
  429.   motif_printf(moves, "%d", movesDsp);
  430. }
  431.  
  432. static void OctaSlider(w, clientData, cbs)
  433.   Widget w;
  434.   XtPointer clientData;
  435.   XmScaleCallbackStruct *cbs;
  436. {
  437.   int size = cbs->value, mode;
  438.   Boolean orient, sticky, practice;
  439.  
  440.   XtVaGetValues(oct,
  441.     XtNsize, &oldSize,
  442.     XtNmode, &mode,
  443.     XtNorient, &orient,
  444.     XtNsticky, &sticky,
  445.     XtNpractice, &practice,
  446.     NULL);
  447.   if (sticky)
  448.     XmScaleSetValue(w, oldSize);
  449.   else if (oldSize != size) {
  450.     XtVaSetValues(oct,
  451.       XtNsize, size,
  452.       NULL);
  453.     oldSize = size;
  454.     movesDsp = 0;
  455.     motif_printf(moves, "%d", movesDsp);
  456.     PrintRecord(size, mode, orient, sticky, practice);
  457.   }
  458. }
  459.  
  460. static void ModeToggle(w, mode, cbs)
  461.   Widget w;
  462.   int mode;
  463.   XmToggleButtonCallbackStruct *cbs;
  464. {
  465.   int size;
  466.   Boolean orient, sticky, practice;
  467.  
  468.   if (cbs->set) {
  469.     XtVaGetValues(oct,
  470.       XtNsize, &size,
  471.       XtNorient, &orient,
  472.       XtNsticky, &sticky,
  473.       XtNpractice, &practice,
  474.       NULL);
  475.     XtVaSetValues(oct,
  476.       XtNmode, mode + PERIOD3,
  477.       NULL);
  478.     movesDsp = 0;
  479.     motif_printf(moves, "%d", movesDsp);
  480.     PrintRecord(size, mode + PERIOD3, orient, sticky, practice);
  481.   }
  482. }
  483.  
  484. static void OrientToggle(w, clientData, cbs)
  485.   Widget w;
  486.   XtPointer clientData;
  487.   XmToggleButtonCallbackStruct *cbs;
  488. {
  489.   int size, mode;
  490.   Boolean orient = cbs->set, sticky, practice;
  491.  
  492.   XtVaGetValues(oct,
  493.     XtNsize, &size,
  494.     XtNmode, &mode,
  495.     XtNsticky, &sticky,
  496.     XtNpractice, &practice,
  497.     NULL);
  498.   XtVaSetValues(oct,
  499.     XtNorient, orient,
  500.     NULL);
  501.   movesDsp = 0;
  502.   motif_printf(moves, "%d", movesDsp);
  503.   PrintRecord(size, mode, orient, sticky, practice);
  504. }
  505.  
  506. static void StickyToggle(w, clientData, cbs)
  507.   Widget w;
  508.   XtPointer clientData;
  509.   XmToggleButtonCallbackStruct *cbs;
  510. {
  511.   int size, mode;
  512.   Boolean orient, sticky = cbs->set, practice;
  513.  
  514.   XtVaGetValues(oct,
  515.     XtNsize, &size,
  516.     XtNmode, &mode,
  517.     XtNorient, &orient,
  518.     XtNpractice, &practice,
  519.     NULL);
  520.   XtVaSetValues(oct,
  521.     XtNsticky, sticky,
  522.     NULL);
  523.   if ((sticky && size != 4) || (!sticky && oldSize != 4)) {
  524.     if (sticky)
  525.       size = 4;
  526.     else
  527.       size = oldSize;
  528.     if (size <= MAXOCTAS)
  529.       XmScaleSetValue(octas, size);
  530.     XtVaSetValues(oct,
  531.       XtNsize, size,
  532.       NULL);
  533.   }
  534.   movesDsp = 0;
  535.   motif_printf(moves, "%d", movesDsp);
  536.   PrintRecord(size, mode, orient, sticky, practice);
  537. }
  538.  
  539. static void PracticeToggle(w, clientData, cbs)
  540.   Widget w;
  541.   XtPointer clientData;
  542.   XmToggleButtonCallbackStruct *cbs;
  543. {
  544.   int size, mode;
  545.   Boolean orient, sticky, practice = cbs->set;
  546.  
  547.   XtVaSetValues(oct,
  548.     XtNpractice, practice,
  549.     XtNstart, FALSE,
  550.     NULL);
  551.   XtVaGetValues(oct,
  552.     XtNsize, &size,
  553.     XtNmode, &mode,
  554.     XtNorient, &orient,
  555.     XtNsticky, &sticky,
  556.     NULL);
  557.   movesDsp = 0;
  558.   motif_printf(moves, "%d", movesDsp);
  559.   if (!practice)
  560.     (void) strcpy(messageDsp, "Randomize to start");
  561.   PrintRecord(size, mode, orient, sticky, practice);
  562. }
  563.  
  564. static void PrintRecord(size, mode, orient, sticky, practice)
  565.   int size, mode;
  566.   Boolean orient, sticky, practice;
  567. {
  568.   int i = mode - PERIOD3;
  569.   int j = (orient) ? 1 : 0;
  570.   int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
  571.  
  572.   if (practice)
  573.     motif_printf(record, "practice");
  574.   else if (!sticky && size > MAXOCTAS)
  575.     motif_printf(record, "NOT RECORDED");
  576.   else if (octRecord[i][j][k] >= MAXRECORD)
  577.     motif_printf(record, "NEVER");
  578.   else
  579.     motif_printf(record, "%d", octRecord[i][j][k]);
  580. }
  581.  
  582. static int HandleSolved(counter, size, mode, orient, sticky)
  583.   int counter, size, mode;
  584.   Boolean orient, sticky;
  585. {
  586.   int i = mode - PERIOD3;
  587.   int j = (orient) ? 1 : 0;
  588.   int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
  589.  
  590.   if ((sticky || size <= MAXOCTAS) && counter < octRecord[i][j][k]) {
  591.     octRecord[i][j][k] = counter;
  592.     if ((size < 2 && mode != PERIOD4) || (size < 4  && mode == PERIOD4) || 
  593.         (orient && (octRecord[i][j][k] < octRecord[i][!j][k])))
  594.       octRecord[i][!j][k] = counter;
  595.     WriteRecords();
  596.     PrintRecord(size, mode, orient, sticky, FALSE);
  597.     return TRUE;
  598.   }
  599.   return FALSE;
  600. }
  601.  
  602. static void ReadRecords()
  603. {
  604.   FILE *fp;
  605.   int i, n, mode, orient;
  606.  
  607.   for (mode = 0; mode < MAXMODES; mode++)
  608.     for (orient = 0; orient < 2; orient++)
  609.       for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
  610.         octRecord[mode][orient][i] = MAXRECORD;
  611.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  612.     motif_printf(message, "Can not open %s, taking defaults.", SCOREFILE);
  613.   else {
  614.     for (mode = 0; mode < MAXMODES; mode++)
  615.       for (orient = 0; orient < 2; orient++)
  616.         for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++) {
  617.           (void) fscanf(fp, "%d", &n);
  618.           octRecord[mode][orient][i] = n;
  619.         }
  620.     (void) fclose(fp);
  621.   }
  622. }
  623.  
  624. static void WriteRecords()
  625. {
  626.   FILE *fp;
  627.   int i, mode, orient;
  628.  
  629.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  630.     motif_printf(message, "Can not write to %s.", SCOREFILE);
  631.   else {
  632.     for (mode = 0; mode < MAXMODES; mode++) {
  633.       for (orient = 0; orient < 2; orient++) {
  634.         for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
  635.           (void) fprintf(fp, "%d ", octRecord[mode][orient][i]);
  636.         (void) fprintf(fp, "\n");
  637.       }
  638.       (void) fprintf(fp, "\n");
  639.     }
  640.     (void) fclose(fp);
  641.   }
  642. }
  643.  
  644. #include <varargs.h>
  645. static void motif_printf(va_alist)
  646.   va_dcl
  647. {
  648.   Widget w;
  649.   char *format;
  650.   va_list args;
  651.   char str[1000];
  652.   Arg wargs[10];
  653.   XmString xmstr;
  654.  
  655.   va_start(args);
  656.   w = va_arg(args, Widget);
  657.   if (!XtIsSubclass(w, xmLabelWidgetClass))
  658.     XtError("motif_printf() requires a Label Widget");
  659.   format = va_arg(args, char *);
  660.   (void) vsprintf(str, format, args);
  661.   xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
  662.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  663.   XtSetValues(w, wargs, 1);
  664.   va_end(args);
  665. }
  666.